#include <fcntl.h>
#include <termios.h>
#include <string.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <stdlib.h>

int set_opt(int fd, int nSpeed, int nBits, char nEvent, int nStop);
int open_port(int fd, int comport);

int main(void)
{
    int fd;
    int nread,nwrite, i;
    
    char buff[8];
    fd_set  rd;
/*
        fd = open("/dev/ttyS0", O_RDWR|O_NOCTTY|O_NDELAY); 
        if(-1 == fd)
        {
            perror("Can't open serial port");
            return -1;
        }
        */
    if((fd = open_port (fd, 1)) < 0)
    {
      perror("open_port error ");
      return -1;
    }
   if((i = set_opt(fd, 115200,8,'N',1)) < 0)
    {

     printf("waiting asd\n");
      perror("set_opt error");
      return -1;
    }
   /*useing select to realize mult-serialport reading and writing*/
   
     printf("waiting zero\n");
     FD_ZERO(&rd);
     printf("waiting 0\n");
     FD_SET(fd, &rd);
     printf("waiting 1\n");
   while(FD_ISSET(fd, &rd))
   {
     printf("waiting 2\n");
        if(select(fd+1,&rd,NULL,NULL,NULL) < 0) 
        {
            perror("select error");
            printf("waiting 3\n");
        }
       else
        {
            printf("waiting 4\n");
            while((nread = read(fd, buff, 8)) > 0) 
            {
                printf("nread=%d,%s\n", nread, buff); 
            }
        }
   }
   printf("waiting 5\n");
   close(fd);
   return 0;
 }

int set_opt(int fd, int nSpeed, int nBits, char nEvent, int nStop)
{
    struct termios newtio, oldtio;
    /*保存测试现有串口参数设置，在这里如果串口号等出错，会有相关的出错信息*/
    if(tcgetattr(fd, &oldtio) != 0)
    {
        perror("SetupSerial 1"); 
        return -1;
    }
    bzero(&newtio, sizeof(newtio));
    /*Set the size of chars*/
    newtio.c_cflag |= CLOCAL|CREAD;
    newtio.c_cflag &= ~CSIZE;
    switch(nBits)
    {
    case 7:
      newtio.c_cflag |= CS7;
      break;
    case 8:
      newtio.c_cflag |= CS8;
      break;
    }
    /*Set the parity checking bit*/
    switch(nEvent)
    {
    case 'O'://奇数
      newtio.c_cflag |= PARENB;
      newtio.c_cflag |= PARODD;
      newtio.c_iflag |= (INPCK | ISTRIP);
      break;
    case 'E'://偶数
      newtio.c_iflag |= (INPCK | ISTRIP);
      newtio.c_cflag |= PARENB;
      newtio.c_cflag &= ~PARODD;
      break;
    case 'N':
      newtio.c_cflag &= ~PARENB;
      break;
     }
    /*Set the baudrate*/
    switch(nSpeed)
    {
    case 2400:
      cfsetispeed(&newtio, B2400);
      cfsetospeed(&newtio, B2400);
      break;
    case 4800:
      cfsetispeed(&newtio, B4800);
      cfsetospeed(&newtio, B4800);
      break;
    case 9600:
      cfsetispeed(&newtio, B9600);
      cfsetospeed(&newtio, B9600);
      break;
    case 115200:
      cfsetispeed(&newtio, B115200);
      cfsetospeed(&newtio, B115200);
      break;
    case 460800:
      cfsetispeed(&newtio, B460800);
      cfsetospeed(&newtio, B460800);
      break;
    default:
      cfsetispeed(&newtio, B9600);
      cfsetospeed(&newtio, B9600);
      break;
    }
    /*Set the stop bit*/
    if(nStop == 1)
    {
        newtio.c_cflag &= ~CSTOPB;
    }
    else if(nStop == 2)
    {
        newtio.c_cflag |= CSTOPB; 
    }
    /*Set the waiting time and the minimum receive char*/
    newtio.c_cc[VTIME] = 0;
    newtio.c_cc[VMIN] = 0;
    /*deal with the unreceived chars*/
    tcflush(fd, TCIFLUSH);
    /*activating the new config*/
    if((tcsetattr(fd, TCSANOW, &newtio)) != 0)
    {
        perror("com set error"); 
        return -1;
    }
    printf("set done!\n");
    return 0;
}

int open_port(int fd, int comport)
{
    char *dev[]={"/dev/ttyS0","/dev/ttyS1","/dev/ttyS2"};
    long vdisable;
    if(comport == 1)
    {
        fd = open("/dev/ttyS0", O_RDWR|O_NOCTTY|O_NDELAY); 
        if(-1 == fd)
        {
            perror("Can't open serial port");
            return -1;
        }
    }
    else if(comport == 2)
    {
        fd = open("/dev/ttyS1", O_RDWR|O_NOCTTY|O_NDELAY); 
        if(-1 == fd)
        {
            perror("Can't open serial port");
            return -1;
        }
    }
    else if(comport == 3)
    {
        fd = open("/dev/ttyS2", O_RDWR|O_NOCTTY|O_NDELAY); 
        if(-1 == fd)
        {
            perror("Can't open serial port");
            return -1;
        }
    }

    /*resume the serial port to blocking state,in order to wait the serial port data to be read*/
    if(fcntl(fd, F_SETFL, 0) < 0)
      printf("fcntl failed!\n");
    else
      printf("fcntl=%d\n",fcntl(fd, F_SETFL, 0));
    /*Whether it is terminal equipmenti,ensure that the serial port was opened correctly*/
    if(isatty(STDIN_FILENO) == 0)
      printf("standard input is not a terminal device\n");
    else
      printf("isatty success!\n");
    return fd;
}
